#include "stdafx.h"

#include "..\TestRunner.h"
using namespace TddGui;

namespace Fast
{
TESTCLASS(TestRunnerTests)
{
	template<HMODULE H, DWORD D>
	struct Mock
	{
		static HMODULE LoadLibrary(...) { return H; }
		static void FreeLibrary(__in HMODULE hModule) { TddAssert().IsTrue(H == hModule); }
		static DWORD GetLastError() { return D; }
	};

	TESTMETHOD(DllWithBadDllName)
	{
		TddAssert().AreEqual(HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND),TestRunnerT<Mock<0,ERROR_FILE_NOT_FOUND>>::IsTestDll(CPath(L"?")));
	}
	TESTMETHOD(DllWithoutEntryPoint)
	{
		TddAssert().AreEqual(HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), TestRunnerT<Mock<(HMODULE)7,ERROR_FILE_NOT_FOUND>>::IsTestDll(CPath(L"?")));
	}

	struct MockHelper : public TestRunnerTests::Mock<(HMODULE)7, 0>
	{
		static void CheckParams(__in HMODULE hModule, __in LPCSTR lpProcName)
		{
			TddAssert().AreEqual(7, reinterpret_cast<int>(hModule));
			TddAssert().AreEqual(L"RunTddTests", lpProcName);
		}
	};
	TESTMETHOD(DllWithNoTests)
	{
		struct Mock : public MockHelper
		{
			static FARPROC GetProcAddress(__in HMODULE hModule, __in LPCSTR lpProcName)
			{
				CheckParams(hModule, lpProcName);
				return reinterpret_cast<FARPROC>(RunNoTests);
			}
		private:
			static void __stdcall RunNoTests(TDD::Discriminator&, TDD::Reporter&) {}
		};
		TddAssert().AreEqual(E_FAIL, TestRunnerT<Mock>::IsTestDll(CPath(L"?")));
	}
	TESTMETHOD(SunnyDay)
	{
		struct Mock : public MockHelper
		{
			static FARPROC GetProcAddress(__in HMODULE hModule, __in LPCSTR lpProcName)
			{
				CheckParams(hModule, lpProcName);
				return reinterpret_cast<FARPROC>(RunTddTests);
			}
		private:
			static void __stdcall RunTddTests(TDD::Discriminator& disc, TDD::Reporter&)
			{
				disc.WantTest(TDD::UnitTestInfo("g", "t"));
			}
		};
		TddAssert().AreEqual(S_OK, TestRunnerT<Mock>::IsTestDll(CPath(L"?")));
	}
};
}